<?php

namespace fadadaApi;

use fadadaApi\data\FddSignContract;
use fadadaApi\data\FddTemplate;

/**
 * 3DES加解密类
 */
class FddEncryption
{

	protected string $app_id     = '';
	protected string $app_secret = '';


	public function __construct(string $app_id, string $app_secret)
	{
		$this->app_id     = $app_id;
		$this->app_secret = $app_secret;
	}

	/**
	 * 兼容PHP7.2 3DES加密
	 *
	 * @param $message
	 *
	 * @return string
	 */
	public function encrypt($message): string
	{
		return bin2hex(openssl_encrypt($message, "des-ede3", $this->app_secret, 1));
	}

	/**
	 * 通用msg_digest加密函数
	 *
	 * @param $param
	 * @param $enc
	 *
	 * @return string
	 */
	public function GeneralDigest($param, $enc): string
	{
		$value   = $param->GetValues();
		$md5Str  = $param->GetTimestamp();
		$sha1Str = $this->app_secret;
		foreach ($enc as $k => $v) {
			switch ($k) {
				case "md5":
					foreach ($v as $md5Key => $md5Value) {
						if (isset($value[$md5Value])) {
							$md5Str .= $value[$md5Value];
						}
					}
					break;
				case "sha1":
					foreach ($v as $sha1Key => $sha1Value) {
						if (isset($value[$sha1Value])) {
							$sha1Str .= $value[$sha1Value];
						}
					}
					break;
			}
		}

		return base64_encode(strtoupper(sha1($this->app_id . strtoupper(md5($md5Str)) . strtoupper(sha1($sha1Str)))));
	}

	/**
	 * 数组参数转字符串格式
	 *
	 * @param $Array
	 *
	 * @return string
	 */
	public function ArrayParamToStr($Array): string
	{
		$Str = "?";
		if (!empty($Array)) {
			foreach ($Array as $k => $v) {
				$Str .= $k . "=" . $v . "&";
			}
		}
		return trim($Str, "&");

	}


	/**
	 * 合同生成msg_digest加密
	 *
	 * @param FddTemplate $param
	 *
	 * @return string
	 */
	public function ContractDigest(FddTemplate $param): string
	{
		$sha1 = $this->app_secret . $param->GetTemplate_id() . $param->GetContract_id();
		return base64_encode(strtoupper(sha1($this->app_id . strtoupper(md5($param->GetTimestamp())) . strtoupper(sha1($sha1)) . $param->GetParameter_map())));
	}

	/**
	 * 文档签署接口（手动签） msg_digest加密
	 *
	 * @param FddSignContract $param
	 *
	 * @return string
	 */
	public function ExtsignDigest(FddSignContract $param): string
	{
		$sha1 = $this->app_secret . $param->GetCustomer_id();
		return base64_encode(strtoupper(sha1($this->app_id . strtoupper(md5($param->GetTransaction_id() . $param->GetTimestamp())) . strtoupper(sha1($sha1)))));
	}

	/**
	 * 文档签署接口（含有效期和次数限制） msg_digest加密
	 *
	 * @param FddSignContract $param
	 *
	 * @return string
	 */
	public function ExtsignValiityDigest(FddSignContract $param): string
	{
		$sha1 = $this->app_secret . $param->GetCustomer_id();
		return base64_encode(strtoupper(sha1($this->app_id . strtoupper(md5($param->GetTransaction_id() . $param->GetTimestamp() . $param->GetValidity() . $param->GetQuantity())) . strtoupper(sha1($sha1)))));
	}

	/**
	 * 授权自动签摘要加密（与通用摘要的区别是，时间戳在尾部）
	 *
	 * @param $param
	 * @param $enc
	 *
	 * @return string
	 */
	public function AuthSignDigest($param, $enc): string
	{
		$value = $param->GetValues();
		// 与通用摘要的区别是，时间戳在尾部
		$md5Str  = '';
		$sha1Str = $this->app_secret;
		foreach ($enc as $k => $v) {
			switch ($k) {
				case "md5":
					foreach ($v as $md5Key => $md5Value) {
						if (isset($value[$md5Value])) {
							$md5Str .= $value[$md5Value];
						}
					}
					break;
				case "sha1":
					foreach ($v as $sha1Key => $sha1Value) {
						if (isset($value[$sha1Value])) {
							$sha1Str .= $value[$sha1Value];
						}
					}
					break;
			}
		}

		$md5Str .= $param->GetTimestamp();

		return base64_encode(strtoupper(sha1($this->app_id . strtoupper(md5($md5Str)) . strtoupper(sha1($sha1Str)))));
	}

}

